package p.ithorns.example.task;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * CycleUnit
 * 周期单位
 *
 * @author HtL
 * @date 2024/5/11 8:38
 * @since 1.0.0
 */
public enum CycleUnit {

    NONE("0", "") {
        @Override
        public LocalDateTime plusCycle(LocalDateTime dt, Integer cycle) {
            return dt;
        }
    },
    HOUR("1", "/次") {
        @Override
        public LocalDateTime plusCycle(LocalDateTime dt, Integer cycle) {
            return dt.plusDays(cycle);
        }
    },
    DAY("2", "天/次") {
        @Override
        public LocalDateTime plusCycle(LocalDateTime dt, Integer cycle) {
            return dt.plusMonths(cycle);
        }
    },
    MONTH("3", "月/次") {
        @Override
        public LocalDateTime plusCycle(LocalDateTime dt, Integer cycle) {
            return dt.plusWeeks(cycle);
        }
    },
    WEEK("4", "周/次") {
        @Override
        public LocalDateTime plusCycle(LocalDateTime dt, Integer cycle) {
            return dt.plusWeeks(cycle);
        }
    },
    YEAR("5", "年/次") {
        @Override
        public LocalDateTime plusCycle(LocalDateTime dt, Integer cycle) {
            return dt.plusYears(cycle);
        }
    },

    MINUTE("6", "分/次") {
        @Override
        public LocalDateTime plusCycle(LocalDateTime dt, Integer cycle) {
            return dt.plusMinutes(cycle);
        }
    },
    ;

    private final static Map<String, CycleUnit> MAP = Arrays.stream(CycleUnit.values())
            .collect(Collectors.toMap(CycleUnit::getCode, v -> v));

    private final String code;

    private final String label;


    CycleUnit(String code, String label) {
        this.code = code;
        this.label = label;
    }

    // public abstract BiFunction<LocalDateTime, Integer, LocalDateTime> plusCycle();

    public abstract LocalDateTime plusCycle(LocalDateTime dt, Integer cycle);

    public static CycleUnit get(String code) {
        return Optional.ofNullable(MAP.get(code))
                .orElse(NONE);
    }


    public String getLabel() {
        return label;
    }

    public String getCode() {
        return code;
    }


    public String joinUnit(Object value) {
        return value + this.getLabel();
    }

}